<template>
	<u-popup ref="popup" :show="popupShow" @close="close">
		<view class="popup-content">
			<!-- 搜索框 -->
			<view style="margin-bottom: 20rpx;" v-if="searchShow">
				<u-search v-model="keyword" @blur="debounceSearch" :placeholder="placeholder" :disabled="disabled"
					:showAction="false"></u-search>
			</view>

			<!-- 滚动列表 -->
			<scroll-view scroll-y :style="{ height: scrollViewHeight }" :enable-back-to-top="true"
				:scroll-with-animation="true" @scrolltolower="loadMore">
				<template v-if="filteredList.length > 0">
					<view v-for="item in filteredList" :key="item[valueKey]" class="list-item"
						:class="{ 'selected-item': isSelected(item) }" @click="selectItem(item)">
						<text class="item-label">{{ item[labelKey] }}</text>
						<u-icon name="checkbox-mark" v-if="isSelected(item)" size="18" color="#3B75FF"></u-icon>
					</view>
				</template>
				<view v-else class="empty-wrapper">
					<text class="empty-text">{{ emptyText }}</text>
				</view>

				<view v-if="loading" class="loading-wrapper">
					<u-loadmore status="loading" loadingText="正在加载..." />
				</view>
				<!-- <view v-if="noMore && filteredList.length > 0" class="loading-wrapper">
					<u-loadmore status="nomore" nomoreText="没有更多数据了" />
				</view> -->
			</scroll-view>

			<!-- 多选确定按钮 -->
			<view v-if="multiple" class="confirm-btn">
				<view class="confirmleft"
					:style="{'width':selectedCount == 0?'100%':'100%','marginRight':selectedCount == 0?'0':'0%'}"
					@click="handleConfirm">确 定</view>
				<!-- <view class="confirmright" v-if="selectedCount > 0" @click="delConfirm">删除已选</view> -->
			</view>
		</view>
	</u-popup>
</template>

<script>
	export default {
		name: 'BottomSelect',
		model: {
			prop: 'value',
			event: 'input'
		},
		props: {
			fetchData: {
				type: Function,
				required: true
			},
			value: {
				type: Object,
				default: () => ({
					ids: [],
					names: []
				}),
				validator: value => {
					return Array.isArray(value.ids) &&
						Array.isArray(value.names) &&
						value.ids.length === value.names.length
				}
			},
			searchShow: Boolean,
			displayText: String,
			emptyText: {
				type: String,
				default: ''
			},
			disabled: Boolean,
			placeholder: {
				type: String,
				default: '请输入关键词搜索'
			},
			scrollHeight: {
				type: String,
				default: '60vh'
			},
			labelKey: {
				type: String,
				default: 'label'
			},
			valueKey: {
				type: String,
				default: 'value'
			},
			multiple: {
				type: Boolean,
				default: false
			}
		},
		data() {
			return {
				popupShow: false,
				keyword: '',
				filteredList: [],
				page: 1,
				pageSize: 20,
				loading: false,
				noMore: false,
				loadText: {
					contentdown: '上拉加载更多',
					contentrefresh: '正在加载...',
					contentnomore: '没有更多数据了'
				}
			};
		},

		computed: {
			selectedValues() {
				return this.value.ids || []
			},
			scrollViewHeight() {
				return this.multiple ? `calc(${this.scrollHeight} - 100rpx)` : this.scrollHeight
			},
			selectedCount() {
				return this.multiple ? this.selectedValues.length : 0
			}
		},

		methods: {
			open() {
				if (this.disabled) return
				this.popupShow = true;
				this.resetState();
				this.keyword = '';
				this.loadData(true);
			},

			close() {
				this.popupShow = false;
			},

			resetState() {
				this.page = 1
				this.filteredList = []
				this.noMore = false
			},

			async loadData(init = false) {
				if (this.loading || this.noMore) return

				this.loading = true
				try {
					const params = {
						page: init ? 1 : this.page,
						num: this.pageSize,
						keyword: this.keyword
					}

					const res = await this.fetchData(params)
					const currentData = res.data.list || [];
					const total = res.data.max;
					if(!total){
						this.filteredList = res.data;
						this.noMore = true;
						return;
					}
					if (init) this.filteredList = currentData
					else this.filteredList = [...this.filteredList, ...currentData]
					this.noMore = this.page * this.pageSize >= total
					this.page = init ? 2 : this.page + 1
				} catch (error) {
					console.error('加载失败:', error)
					this.$emit('error', error)
				} finally {
					this.loading = false
				}
			},

			handleSearch() {
				this.resetState()
				this.loadData(true)
			},

			debounceSearch: debounce(function() {
				this.handleSearch()
			}, 300),

			loadMore() {
				if (!this.noMore) this.loadData()
			},

			isSelected(item) {
				return this.selectedValues.includes(item[this.valueKey])
			},

			selectItem(item) {
				if (this.disabled) return

				const value = item[this.valueKey]
				const label = item[this.labelKey]
				const newValue = JSON.parse(JSON.stringify(this.value)) // 深拷贝原值

				if (this.multiple) {
					const index = newValue.ids.indexOf(value)
					if (index > -1) {
						newValue.ids.splice(index, 1)
						newValue.names.splice(index, 1)
					} else {
						newValue.ids.push(value)
						newValue.names.push(label) // 同步label
					}
				} else {
					newValue.ids = [value]
					newValue.names = [label] // 同步label
					this.close()

					this.$emit('select', {
						value,
						label,
						rawData: item
					})
				}
				this.$emit('input', newValue)

			},
			delConfirm() {
				this.value.ids = [];
				this.value.names = [];
			},
			handleConfirm() {
				this.close()
				this.$emit('confirm', {
					ids: this.value.ids,
					names: this.value.names
				})
			}
		}
	}

	function debounce(fn, delay) {
		let timer
		return function(...args) {
			clearTimeout(timer)
			timer = setTimeout(() => fn.apply(this, args), delay)
		}
	}
</script>

<style lang="scss" scoped>
	.popup-content {
		background: #fff;
		border-radius: 24rpx 24rpx 0 0;
		padding: 24rpx;
		box-sizing: border-box;
		position: relative;
		min-height: 40vh;
		max-height: 80vh;
		padding-bottom: 120rpx;
	}

	scroll-view {
		height: 100%;
	}

	.list-item {
		padding: 28rpx 32rpx;
		border-bottom: 1rpx solid #f5f5f5;
		display: flex;
		justify-content: space-between;
		align-items: center;
		transition: all 0.2s;
	}

	.list-item:active {
		background-color: #f9f9f9;
	}

	.selected-item {
		background-color: #f5f8ff;
	}

	.item-label {
		font-size: 28rpx;
		color: #333;
	}

	.empty-wrapper {
		padding: 48rpx 0;
		text-align: center;
	}

	.empty-text {
		font-size: 26rpx;
		color: #999;
	}

	.loading-wrapper {
		padding: 24rpx 0;
	}

	.confirm-btn {
		position: fixed;
		bottom: 30rpx;
		left: 24rpx;
		right: 24rpx;
		height: 80rpx;
		line-height: 80rpx;
		display: flex;

	}

	.confirmleft {
		width: 78%;
		height: 80rpx;
		line-height: 80rpx;
		background: #3B75FF;
		color: #fff;
		text-align: center;
		border-radius: 16rpx;
		font-size: 30rpx;
		margin-right: 2%;
		box-shadow: 0 4rpx 12rpx rgba(0, 122, 255, 0.3);
	}

	.confirmright {
		width: 20%;
		height: 80rpx;
		line-height: 80rpx;
		background: #f5f5f5;
		color: #000;
		text-align: center;
		border-radius: 16rpx;
		font-size: 30rpx;
		box-shadow: 0 4rpx 12rpx rgba(0, 122, 255, 0.3);
	}
</style>